/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
 * Description: Parse dts information from aac's head
 * Author: HiMobileCam middleware develop team
 * Create: 2017-12-22
 */

#include "ffaacparser.h"

#include "securec.h"

#include "../ffdemux_common.h"
#include "../ffdemux_log.h"
#include "ffbitsreader.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/* ISO-13318-7 2003  https://wiki.multimedia.cx/index.php/ADTS */
HI_S32 FFAACParserParseAdtsHeader(const HI_U8 *data, HI_U32 dataLen,
    AacAdtsHeader *outHeader, HI_U32 *outHeaderLen)
{
    if ((data == HI_NULL) || (dataLen == 0) || (outHeader == HI_NULL) || (outHeaderLen == HI_NULL)) {
        return HI_FAILURE;
    }

    FfBitReader *bitReader = HI_NULL;
    HI_S32 ret = FFBitsReaderCreate(&bitReader, data, dataLen);
    if (ret != HI_SUCCESS) {
        return HI_FAILURE;
    }

    AacAdtsHeader adtsHeader = { 0 };
    adtsHeader.sync = FfBitReadUN(bitReader, 12); /* syncword */
    if (adtsHeader.sync != (HI_U32)0xFFF) {
        FFDEMUX_PRINTF(MODULE_NAME_DEMUX, HI_FFDEMUX_LOG_LEVEL_ERR, "audio syncword error %x \n", adtsHeader.sync);
        ret = HI_FAILURE;
        goto error;
    }

    adtsHeader.id = FfBitReadU1(bitReader);         /* ID */
    adtsHeader.layer = FfBitReadU2(bitReader);      /* layer */
    adtsHeader.protectBit = FfBitReadU1(bitReader); /* protection_absent */
    adtsHeader.pofile = FfBitReadU2(bitReader);    /* profile_objecttype */
    adtsHeader.sampRateIdx = FfBitReadU4(bitReader);
    adtsHeader.privateBit = FfBitReadU1(bitReader); /* private_bit */
    adtsHeader.channelConfig = FfBitReadU3(bitReader);  /* channel_configuration */

    adtsHeader.origCopy = FfBitReadU1(bitReader); /* original_copy */
    adtsHeader.home = FfBitReadU1(bitReader);     /* home */

    /* adts_variable_header */
    adtsHeader.copyBit = FfBitReadU1(bitReader);   /* copyright_identification_bit */
    adtsHeader.copyStart = FfBitReadU1(bitReader); /* copyright_identification_start */
    adtsHeader.frameLength = FfBitReadUN(bitReader, 13);  /* aac_frame_length */
    adtsHeader.bufferFull = FfBitReadUN(bitReader, 11);  /* adts_buffer_fullness */
    adtsHeader.numRawDataBlocks = FfBitReadU2(bitReader); /* number_of_raw_data_blocks_in_frame */

    HI_U32 headerLen = 7;
    if (adtsHeader.protectBit == 0) {
        adtsHeader.crcCheckWord = FfBitReadU16(bitReader); /* 16-bit CRC check word (present if protectBit == 0) */
        headerLen = 9;
    }

    if (memcpy_s(outHeader, sizeof(AacAdtsHeader), &adtsHeader, sizeof(AacAdtsHeader)) != EOK) {  // get atds info
        FFDEMUX_PRINTF(MODULE_NAME_DEMUX, HI_FFDEMUX_LOG_LEVEL_ERR, "copy header error \n");
        ret = HI_FAILURE;
    } else {
        *outHeaderLen = headerLen;
    }
error:
    if (FFBitsReaderDestroy(bitReader) != HI_SUCCESS) {
        FFDEMUX_PRINTF(MODULE_NAME_DEMUX, HI_FFDEMUX_LOG_LEVEL_ERR, "FFBitsReaderDestroy error \n");
    }

    return ret;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
